package view;

import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.List;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JToolBar;


/**
 * This class will house the menubar at the
 * top of the gui. 
 * 
 * @author Tristan D. Boucher
 * @version Commit #22 9/14/2013
 *
 */
@SuppressWarnings("serial")
public class GUIMenuBar extends JMenuBar
{ 
  /**
   * The controller associated with this gui component.
   */
  private final GUIController my_controller;

  /**
   * The arraylist of Action objects related to the file menu.
   */
  private final List<Action> my_file_actions;

  /**
   * The arraylist of Action objects related to the options menu.
   */
  private final List<Action> my_option_actions;

  /**
   * The arraylist of Action objects related to the view menu.
   */
  private final List<Action> my_view_actions;

  /**
   * The arraylist of Action objects related to the Help menu.
   */
  private final List<Action> my_help_actions;

  /**
   * Constructor.
   * 
   * @param the_controller The GUI controller object that this
   * component reports to.
   */
  public GUIMenuBar(final GUIController the_controller)
  {
    super();

    my_controller = the_controller;
    my_file_actions = new ArrayList<Action>();
    my_option_actions = new ArrayList<Action>();
    my_view_actions = new ArrayList<Action>();
    my_help_actions = new ArrayList<Action>();

    createActions();
    buildMenuBar();

  }

  /**
   * Creates all the actions for the tool bar and the menubar.
   */
  private void createActions()
  {
    createFileActions();
    createOptionsActions();
    createViewActions();
    createHelpActions();
  }

  /**
   * Creates the actions for the file menu.
   */
  private void createFileActions()
  {
    my_file_actions.add(new AbstractAction("Open...")
    {
      public void actionPerformed(final ActionEvent the_event)
      {  
        my_controller.postOpen();
      }
    });
    my_file_actions.get(0).putValue(Action.SELECTED_KEY, false);
    my_file_actions.get(0).putValue(Action.SHORT_DESCRIPTION, 
        "Opens a schedule file. (.csv)");


    my_file_actions.add(new AbstractAction("Save As...")
    {
      public void actionPerformed(final ActionEvent the_event)
      {  
        my_controller.postSave();
      }
    });
    my_file_actions.get(1).putValue(Action.SELECTED_KEY, false);
    my_file_actions.get(1).putValue(Action.SHORT_DESCRIPTION, "Allows the user to " +
        "save the schedule shown as a .csv file.");


    my_file_actions.add(new AbstractAction("Quit")
    {
      public void actionPerformed(final ActionEvent the_event)
      {  
        my_controller.postQuit();
      }
    });
    my_file_actions.get(2).putValue(Action.SELECTED_KEY, false);
    my_file_actions.get(2).putValue(Action.SHORT_DESCRIPTION, "Exits the program");
  }

  /**
   * Creates the actions for the Options menu.
   */
  private void createOptionsActions()
  {
    my_option_actions.add(new AbstractAction("Logout")
    {
      public void actionPerformed(final ActionEvent the_event)
      {  
        my_controller.postLogout();
      }
    });
    my_option_actions.get(0).putValue(Action.SELECTED_KEY, false);
    my_option_actions.get(0).putValue(Action.SHORT_DESCRIPTION, 
        "Logs the current User out.");
    
    my_option_actions.add(new AbstractAction("Promote User")
    {
      public void actionPerformed(final ActionEvent the_event)
      {  
        my_controller.showPromotionWindow();
      }
    });
    my_option_actions.get(1).putValue(Action.SELECTED_KEY, false);
    my_option_actions.get(1).putValue(Action.SHORT_DESCRIPTION, 
        "Administrator only, shows the promotion window.");
  }
  
  /**
   * Creates the actions for the View menu.
   */
  private void createViewActions()
  {
    my_view_actions.add(new AbstractAction("Full Schedule")
    {
      public void actionPerformed(final ActionEvent the_event)
      {  
        my_controller.postScheduleEditor();
      }
    });
    my_view_actions.get(0).putValue(Action.SELECTED_KEY, false);
    my_view_actions.get(0).putValue(Action.SHORT_DESCRIPTION, 
                                    "Shows the entire schedule/schedule editor, " +
        "depending on status.");


    my_view_actions.add(new AbstractAction("Personal Schedule")
    {
      public void actionPerformed(final ActionEvent the_event)
      {  
        my_controller.postIndividualSchedule();
      }
    });
    my_view_actions.get(1).putValue(Action.SELECTED_KEY, false);
    my_view_actions.get(1).putValue(Action.SHORT_DESCRIPTION, 
        "Shows your individual schedule.");


    my_view_actions.add(new AbstractAction("Availability Editor")
    {
      public void actionPerformed(final ActionEvent the_event)
      {  
        my_controller.postAvailabilityEditorStatic();
      }
    });
    my_view_actions.get(2).putValue(Action.SELECTED_KEY, false);
    my_view_actions.get(2).putValue(Action.SHORT_DESCRIPTION, 
                                    "Shows your availability as it was" +
        " entered. May not be modified.");
  }

  /**
   * Creates the actions for the Help menu.
   */
  private void createHelpActions()
  {
    my_help_actions.add(new AbstractAction("About")
    {
      public void actionPerformed(final ActionEvent the_event)
      {  
        my_controller.postAbout();
      }
    });
    my_help_actions.get(0).putValue(Action.SELECTED_KEY, false);
    my_help_actions.get(0).putValue(Action.SHORT_DESCRIPTION, "Shows a short description " +
        "of the program credentials.");


    my_help_actions.add(new AbstractAction("Program Help")
    {
      public void actionPerformed(final ActionEvent the_event)
      {  
        my_controller.postHelp();
      }
    });
    my_help_actions.get(1).putValue(Action.SELECTED_KEY, false);
    my_help_actions.get(1).putValue(Action.SHORT_DESCRIPTION, "Shows a description of " +
        "how to use the current portion of the program.");
  }

  /**
   * Refreshes this menu bar with new options based upon different users' status'.
   * 
   * @return The refreshed menu bar.
   */
  public GUIMenuBar rebuild()
  {
    this.removeAll();
    return buildMenuBar();
  }
  
  /**
   * The menu object fully constructed.
   * 
   * @return The menu bar.
   */
  private GUIMenuBar buildMenuBar()
  {
    final JMenu file_menu = new JMenu("File");
    final JMenu options_menu = new JMenu("Options");
    final JMenu view_menu = new JMenu("View");
    final JMenu help_menu = new JMenu("Help");

    this.add(file_menu);
    this.add(options_menu);
    this.add(view_menu);
    this.add(help_menu);

    //Put together the File menu.
    file_menu.add(new JMenuItem(my_file_actions.get(0)));
    file_menu.addSeparator();
    file_menu.add(new JMenuItem(my_file_actions.get(1)));
    file_menu.addSeparator();
    file_menu.add(new JMenuItem(my_file_actions.get(2)));

    //Put together the Options menu.
    options_menu.add(my_option_actions.get(0));
    if (my_controller.isUserAdministrator())
    {
      options_menu.add(my_option_actions.get(1));
    }

    //Put together the View menu.
    view_menu.add(new JMenuItem(my_view_actions.get(0)));
    view_menu.addSeparator();
    view_menu.add(new JMenuItem(my_view_actions.get(1)));
    view_menu.addSeparator();
    view_menu.add(new JMenuItem(my_view_actions.get(2)));

    //Put together the Help menu.
    help_menu.add(new JMenuItem(my_help_actions.get(0)));
    help_menu.addSeparator();
    help_menu.add(new JMenuItem(my_help_actions.get(1)));
    help_menu.addSeparator();

    //Set Mnemonics
    file_menu.setMnemonic('F');
    options_menu.setMnemonic('O');
    view_menu.setMnemonic('V');
    help_menu.setMnemonic('H');
    
    return this;
  }
  
  /**
   * Spawns a JToolBar object that will be associated with view switching.
   * 
   * @return A nice JToolBar with the view actions in it.
   */
  public JToolBar spawnToolBar()
  {
    final JToolBar tool_bar = new JToolBar();
    
    for (int i = 0; i < my_view_actions.size(); i++)
    {
      tool_bar.add(my_view_actions.get(i));
    }
    
    return tool_bar;
  }
}
